package com.meilai.project.service.business.workbench.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.meilai.project.constant.BossUserEnum;
import com.meilai.project.dto.business.workbench.SplitAnnualTargetDTO;
import com.meilai.project.entity.business.contract.ContractApply;
import com.meilai.project.entity.business.customer.CustomerInfo;
import com.meilai.project.entity.business.workbench.*;
import com.meilai.project.exception.CommonException;
import com.meilai.project.mapper.business.contract.ContractApplyMapper;
import com.meilai.project.mapper.business.workbench.SaleYearTargetMapper;
import com.meilai.project.mapper.business.workbench.YearMapper;
import com.meilai.project.service.business.customer.CustomerInfoService;
import com.meilai.project.service.business.workbench.SaleWeekCustomerTargetService;
import com.meilai.project.service.business.workbench.SaleWeekTargetService;
import com.meilai.project.service.business.workbench.SaleYearTargetService;
import com.meilai.project.service.business.workbench.YearWeekService;
import com.meilai.project.vo.business.workbench.*;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 销售年度目标记录表 服务实现类
 * </p>
 *
 * @author haiYangXu
 * @since 2022-08-16
 */
@Service
public class SaleYearTargetServiceImpl extends ServiceImpl<SaleYearTargetMapper, SaleYearTarget> implements SaleYearTargetService {
    private final static BigDecimal hundred = new BigDecimal(100);

    private final static BigDecimal ten_thousand = new BigDecimal(10000);

    @Autowired
    private YearMapper yearMapper;

    @Autowired
    private YearWeekService yearWeekService;

    @Autowired
    private ContractApplyMapper contractApplyMapper;

    @Autowired
    private CustomerInfoService customerInfoService;

    @Autowired
    private SaleWeekTargetService saleWeekTargetService;

    @Autowired
    private SaleWeekCustomerTargetService saleWeekCustomerTargetService;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean add(SplitAnnualTargetDTO dto) {
        // 检查年数据是否保存
        Year one = yearMapper.selectOne(Wrappers.<Year>lambdaQuery().eq(Year::getYear, dto.getYear()).eq(Year::getType, dto.getType()));
        if (one == null) {
            // 保存年度数据
            Year year = new Year();
            year.setYear(dto.getYear().toString());
            year.setType(dto.getType());
            year.setTarget(dto.getTarget());
            yearMapper.insert(year);
            // 保存周时间数据
            yearWeekService.saveBatch(dto.getWeekList().stream().map(item -> {
                YearWeek yearWeek = new YearWeek();
                yearWeek.setYear_id(year.getId());
                yearWeek.setMonth(item.getStart_date().getMonthValue());
                yearWeek.setBegin_date(item.getStart_date());
                yearWeek.setEnd_date(item.getEnd_date());
                return yearWeek;
            }).collect(Collectors.toList()));
            // 保存新的销售每年度的目标数据
            this.saveBatch(dto.getUserTargetList().stream().map(item -> {
                SaleYearTarget saleYearTarget = new SaleYearTarget();
                saleYearTarget.setYear_id(year.getId());
                saleYearTarget.setUser_id(item.getUser_id());
                saleYearTarget.setTarget_quota(item.getTarget());
                return saleYearTarget;
            }).collect(Collectors.toList()));
        } else {
            throw new CommonException("此年度的目标数据已经存在,请联系管理员");
        }
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean replenish(SplitAnnualTargetDTO dto) {
        Year one = yearMapper.selectOne(Wrappers.<Year>lambdaQuery().eq(Year::getYear, dto.getYear()).eq(Year::getType, dto.getType()));
        // 清空之前的数据
        this.remove(Wrappers.<SaleYearTarget>lambdaQuery().eq(SaleYearTarget::getYear_id, one.getId()));
        // 保存新的销售每年度的目标数据
        this.saveBatch(dto.getUserTargetList().stream().map(item -> {
            SaleYearTarget saleYearTarget = new SaleYearTarget();
            saleYearTarget.setYear_id(one.getId());
            saleYearTarget.setUser_id(item.getUser_id());
            saleYearTarget.setTarget_quota(item.getTarget());
            return saleYearTarget;
        }).collect(Collectors.toList()));
        return true;
    }

    @Override
    public Page<YearTargetVO> selectPage(Integer current_page, Integer page_size, Integer year) {
        Page<YearTargetVO> page = new Page<>(current_page, page_size);
        List<YearTargetVO> list = yearMapper.page(page, year);
        if (CollectionUtils.isNotEmpty(list)) {
            List<Long> ids = list.stream().map(Year::getId).collect(Collectors.toList());
            List<SaleYearTargetVO> dataList = baseMapper.selectByYearIds(ids);
            Map<Long, List<SaleYearTargetVO>> dataMap = dataList.stream().collect(Collectors.groupingBy(SaleYearTargetVO::getYear_id));
            list.forEach(item -> {
                if (dataMap.containsKey(item.getId())) {
                    List<SaleYearTargetVO> saleYearTargetVOS = dataMap.get(item.getId());
                    item.setUserYearTargetList(saleYearTargetVOS);
                } else {
                    item.setUserYearTargetList(new ArrayList<>());
                }
            });
        }
        page.setRecords(list);
        return page;
    }

    @Override
    public YearTargetDetailVO detail(Long year_id) {
        Year year = yearMapper.selectById(year_id);
        if (year == null) {
            throw new CommonException("数据不存在");
        }
        YearTargetDetailVO vo = new YearTargetDetailVO();
        BeanUtils.copyProperties(year, vo);
        // 查询周数据
        List<YearWeek> list = yearWeekService.list(Wrappers.<YearWeek>lambdaQuery().eq(YearWeek::getYear_id, year_id));
        vo.setWeekList(list.stream().map(item -> {
            BaseYearWeekVO weekVO = new BaseYearWeekVO();
            BeanUtils.copyProperties(item, weekVO);
            return weekVO;
        }).collect(Collectors.toList()));
        // 查询用户数据
        List<Long> ids = new ArrayList<>();
        ids.add(year_id);
        List<SaleYearTargetVO> saleYearTargetVOS = baseMapper.selectByYearIds(ids);
        // 查询年度合同
        LocalDate begin_date, end_date;
        if (year.getType() == 1) {
            begin_date = LocalDate.of(Integer.parseInt(year.getYear()), 1, 1);
            end_date = LocalDate.of(Integer.parseInt(year.getYear()), 6, 30);
        } else {
            begin_date = LocalDate.of(Integer.parseInt(year.getYear()), 7, 1);
            end_date = LocalDate.of(Integer.parseInt(year.getYear()), 12, 31);
        }
        List<ContractApply> contractApplyList = contractApplyMapper.queryEffectiveContractList(begin_date, end_date, null);
        saleYearTargetVOS.forEach(item -> {
            List<ContractApply> collect = contractApplyList.stream().filter(contract -> contract.getFlow_applyer_id().equals(item.getUser_id())).collect(Collectors.toList());
            BigDecimal complete_amount = new BigDecimal(0);
            for (ContractApply contract : collect) {
                complete_amount = complete_amount.add(contract.getDiscounted_price());
            }
            complete_amount = complete_amount.divide(ten_thousand, 2, RoundingMode.HALF_UP);
            item.setComplete_amount(complete_amount);
        });
        vo.setUserTargetList(saleYearTargetVOS);
        return vo;
    }

    @Override
    public SaleYearTargetSummaryVO querySaleYearTargetSummary(Integer year, Integer type, Long user_id) {
        List<Long> boss_ids = new ArrayList<>(Arrays.asList(BossUserEnum.values())).stream().map(BossUserEnum::getId).collect(Collectors.toList());
        LocalDate begin_date, end_date;
        if (type == 1) {
            begin_date = LocalDate.of(year, 1, 1);
            end_date = LocalDate.of(year, 6, 30);
        } else {
            begin_date = LocalDate.of(year, 7, 1);
            end_date = LocalDate.of(year, 12, 31);
        }
        // 先查询出年度数据
        Year yearData = yearMapper.selectOne(Wrappers.<Year>lambdaQuery().eq(Year::getYear, year).eq(Year::getType, type));
        SaleYearTargetSummaryVO vo = new SaleYearTargetSummaryVO();
        vo.setYear(year.toString());
        vo.setType(type);
        if (yearData == null) {
            return vo;
        }
        SaleYearTarget saleYearTarget = this.getOne(Wrappers.<SaleYearTarget>lambdaQuery().eq(SaleYearTarget::getYear_id, yearData.getId()).eq(SaleYearTarget::getUser_id, user_id));
        if (saleYearTarget == null) {
            throw new CommonException("此年度主管未给您设置目标，请先设置年度目标");
        }
        vo.setSum(saleYearTarget.getTarget_quota());
        // 查询周数据
        List<YearWeek> weekList = yearWeekService.list(Wrappers.<YearWeek>lambdaQuery().eq(YearWeek::getYear_id, yearData.getId()));
        // 找出需要查询的周id集合
        List<Long> week_ids = weekList.stream().map(YearWeek::getId).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(week_ids)) {
            week_ids.add(-1L);
        }
        // 查询出用户每周的目标
        List<SaleWeekTarget> saleWeekTargetList = saleWeekTargetService.list(Wrappers.<SaleWeekTarget>lambdaQuery().eq(SaleWeekTarget::getUser_id, user_id).in(SaleWeekTarget::getWeek_id, week_ids));
        if (CollectionUtils.isEmpty(saleWeekTargetList)) {
            // 未填写目标 设置可填写
            vo.setNeed_fill(true);
        }
//        // 按月分出每周的数据
//        Map<Integer, List<YearWeek>> month_week_map = weekList.stream().collect(Collectors.groupingBy(YearWeek::getMonth));
        // 查出当前人跟进的客户
        List<CustomerInfo> customer_info_list = customerInfoService.list(Wrappers.<CustomerInfo>lambdaQuery().eq(CustomerInfo::getMaintenance_staff_id, user_id).isNull(CustomerInfo::getDeleted_at));
        Map<Long, List<CustomerInfo>> customer_info_map = customer_info_list.stream().collect(Collectors.groupingBy(CustomerInfo::getId));
        List<Long> customer_ids = customer_info_list.stream().map(CustomerInfo::getId).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(customer_ids)) {
            customer_ids.add(-1L);
        }
        Map<Long, List<SaleWeekCustomerTarget>> sale_week_customer_target_map = saleWeekCustomerTargetService.list(Wrappers.<SaleWeekCustomerTarget>lambdaQuery().eq(SaleWeekCustomerTarget::getUser_id, user_id).in(SaleWeekCustomerTarget::getWeek_id, week_ids).in(SaleWeekCustomerTarget::getCustomer_id, customer_ids)).stream().collect(Collectors.groupingBy(SaleWeekCustomerTarget::getWeek_id));
        List<Long> company_customer_ids = customer_info_list.stream().filter(item -> boss_ids.contains(item.getPerson_in_charge_id())).map(CustomerInfo::getId).collect(Collectors.toList());
        List<Long> my_customer_ids = customer_info_list.stream().filter(item -> !boss_ids.contains(item.getPerson_in_charge_id())).map(CustomerInfo::getId).collect(Collectors.toList());
        // 查询出合同
        List<ContractApply> contractApplyList = contractApplyMapper.queryEffectiveContractList(begin_date, end_date, customer_ids).stream().filter(contract -> contract.getFlow_applyer_id().equals(user_id)).collect(Collectors.toList());
        // 查询出当前人的每周需要拜访的客户数据
        List<MonthTargetVO> month_target_list = new ArrayList<>();

        BigDecimal amount_completed = new BigDecimal(0);

        BigDecimal zero = new BigDecimal(0).setScale(2, RoundingMode.HALF_UP);
        List<WeekCompletionDetailVO> weekCompletionDetailVOList = new ArrayList<>();
        // 组装数据
        for (YearWeek week : weekList) {
            WeekCompletionDetailVO weekCompletionDetailVO = new WeekCompletionDetailVO();
            weekCompletionDetailVO.setId(week.getId());
            weekCompletionDetailVO.setYear_id(week.getYear_id());
            weekCompletionDetailVO.setMonth(week.getMonth());
            weekCompletionDetailVO.setBegin_date(week.getBegin_date());
            weekCompletionDetailVO.setEnd_date(week.getEnd_date());
            // 找到本周需要拜访客户
            List<CustomerInfo> collect = customer_info_list.stream().filter(customer -> customer.getNext_visit_time() != null
                    && (customer.getNext_visit_time().isAfter(week.getBegin_date()) || customer.getNext_visit_time().equals(week.getBegin_date()))
                    && (customer.getNext_visit_time().isBefore(week.getEnd_date()) || customer.getNext_visit_time().equals(week.getEnd_date()))).collect(Collectors.toList());
            // 找出本周设定目标的客户数据
            List<SaleWeekCustomerTarget> saleWeekCustomerTargetList = sale_week_customer_target_map.get(week.getId());
            if (saleWeekCustomerTargetList == null) {
                saleWeekCustomerTargetList = new ArrayList<>();
            }
            List<WeekCompletionTypeVO> weekCompletionTypeVOList = new ArrayList<>();
            BigDecimal week_target = new BigDecimal(0);
            for (int i = 1; i < 3; i++) {
                int index = i;
                List<SaleWeekTarget> saleWeekTarget = saleWeekTargetList.stream().filter(item -> item.getWeek_id().equals(week.getId()) && item.getType() == index).collect(Collectors.toList());
                List<SaleWeekCustomerTarget> list;
                List<ContractApply> contractList;
                List<CustomerInfo> customerInfoList;
                if (i == 1) {//如果是公司
                    customerInfoList = collect.stream().filter(item -> boss_ids.contains(item.getPerson_in_charge_id())).collect(Collectors.toList());
                    list = saleWeekCustomerTargetList.stream().filter(item -> company_customer_ids.contains(item.getCustomer_id())).collect(Collectors.toList());
                    // 获取出符合时间段的客户合同数据
                    contractList = contractApplyList.stream().filter(item -> company_customer_ids.contains(item.getCustomer_id()) && (item.getSign_date().isAfter(week.getBegin_date()) || item.getSign_date().equals(week.getBegin_date())) && (item.getSign_date().isBefore(week.getEnd_date()) || item.getSign_date().equals(week.getEnd_date()))).collect(Collectors.toList());
                } else {// 如果是个人
                    customerInfoList = collect.stream().filter(item -> !boss_ids.contains(item.getPerson_in_charge_id())).collect(Collectors.toList());
                    list = saleWeekCustomerTargetList.stream().filter(item -> my_customer_ids.contains(item.getCustomer_id())).collect(Collectors.toList());
                    // 获取出符合时间段的客户合同数据
                    contractList = contractApplyList.stream().filter(item -> my_customer_ids.contains(item.getCustomer_id()) && (item.getSign_date().isAfter(week.getBegin_date()) || item.getSign_date().equals(week.getBegin_date())) && (item.getSign_date().isBefore(week.getEnd_date()) || item.getSign_date().equals(week.getEnd_date()))).collect(Collectors.toList());
                }
                // 加入每周的维护和个人的成交客户数据
                List<WeekTransactedCustomerVO> weekTransactedCustomerVOList = new ArrayList<>();
                for (SaleWeekCustomerTarget target : list) {
                    WeekTransactedCustomerVO weekTransactedCustomerVO = new WeekTransactedCustomerVO();
                    weekTransactedCustomerVO.setTarget(target.getTarget_quota());
                    if (customer_info_map.containsKey(target.getCustomer_id())) {
                        weekTransactedCustomerVO.setName(customer_info_map.get(target.getCustomer_id()).get(0).getName());
                        weekTransactedCustomerVO.setId(customer_info_map.get(target.getCustomer_id()).get(0).getId());
                    } else {
                        weekTransactedCustomerVO.setName("未知");
                        weekTransactedCustomerVO.setId(-1L);
                    }
                    weekTransactedCustomerVOList.add(weekTransactedCustomerVO);
                }
                WeekCompletionTypeVO weekCompletionTypeVO = new WeekCompletionTypeVO();
                // 设置需要拜访的客户数据
                weekCompletionTypeVO.setNeed_visit_customer_list(
                        customerInfoList.stream().map(item -> {
                            BaseWeekCustomerVO customerVO = new BaseWeekCustomerVO();
                            customerVO.setId(item.getId());
                            customerVO.setName(item.getName());
                            customerVO.setNext_visit_time(item.getNext_visit_time());
                            return customerVO;
                        }).collect(Collectors.toList())
                );
                weekCompletionTypeVO.setType(i);
                if (CollectionUtils.isNotEmpty(saleWeekTarget)) {
                    weekCompletionTypeVO.setTarget(saleWeekTarget.get(0).getTarget_quota());
                } else {
                    weekCompletionTypeVO.setTarget(zero);
                }
                week_target = week_target.add(weekCompletionTypeVO.getTarget());
                BigDecimal week_type_amount_count = new BigDecimal(0);
                // 统计完成金额
                for (ContractApply contractApply : contractList) {
                    week_type_amount_count = week_type_amount_count.add(contractApply.getDiscounted_price());
                }
                if (week_type_amount_count.compareTo(zero) > 0) {
                    // 单位从元换到万元
                    week_type_amount_count = week_type_amount_count.divide(ten_thousand, 2, RoundingMode.HALF_UP);
                    weekCompletionTypeVO.setAmount_completed(week_type_amount_count);
                    if (weekCompletionTypeVO.getTarget().compareTo(zero) > 0) {
                        weekCompletionTypeVO.setCompletion_rate(week_type_amount_count.multiply(hundred).divide(weekCompletionTypeVO.getTarget(), 2, RoundingMode.HALF_UP));
                    } else {
                        weekCompletionTypeVO.setCompletion_rate(zero);
                    }
                } else {
                    weekCompletionTypeVO.setAmount_completed(zero);
                    weekCompletionTypeVO.setCompletion_rate(zero);
                }
                weekCompletionTypeVO.setWeekTransactedCustomerVOList(weekTransactedCustomerVOList);
                weekCompletionTypeVOList.add(weekCompletionTypeVO);
            }
            weekCompletionDetailVO.setWeekCompletionTypeVOList(weekCompletionTypeVOList);
            weekCompletionDetailVO.setTarget(week_target);
            weekCompletionDetailVOList.add(weekCompletionDetailVO);
        }
        // 按照月进行分组
        Map<Integer, List<WeekCompletionDetailVO>> listMap = weekCompletionDetailVOList.stream().collect(Collectors.groupingBy(WeekCompletionDetailVO::getMonth));
        Set<Integer> keys = listMap.keySet();
        for (Integer key : keys) {
            MonthTargetVO monthTargetVO = new MonthTargetVO();
            monthTargetVO.setMonth(key);
            List<WeekCompletionDetailVO> tmp = listMap.get(key);
            BigDecimal month_count = new BigDecimal(0);
            BigDecimal month_amount_count = new BigDecimal(0);
            BigDecimal uphold_target_sum = new BigDecimal(0);
            BigDecimal personal_target_sum = new BigDecimal(0);
            BigDecimal uphold_completed_sum = new BigDecimal(0);
            BigDecimal personal_completed_sum = new BigDecimal(0);
            for (WeekCompletionDetailVO weekCompletionDetailVO : tmp) {
                month_count = month_count.add(weekCompletionDetailVO.getTarget());
                for (WeekCompletionTypeVO weekCompletionTypeVO : weekCompletionDetailVO.getWeekCompletionTypeVOList()) {
                    if (weekCompletionTypeVO.getType() == 1) { // 如果是公司
                        uphold_target_sum = uphold_target_sum.add(weekCompletionTypeVO.getTarget());
                        uphold_completed_sum = uphold_completed_sum.add(weekCompletionTypeVO.getAmount_completed());
                    } else {
                        personal_target_sum = personal_target_sum.add(weekCompletionTypeVO.getTarget());
                        personal_completed_sum = personal_completed_sum.add(weekCompletionTypeVO.getAmount_completed());
                    }
                    month_amount_count = month_amount_count.add(weekCompletionTypeVO.getAmount_completed());
                }
            }
            // todo 新增月度维护目标 完成金额 完成率统计 分为个人和公司
            monthTargetVO.setUphold_target(uphold_target_sum);
            monthTargetVO.setPersonal_target(personal_target_sum);
            monthTargetVO.setUphold_completed(uphold_completed_sum);
            monthTargetVO.setPersonal_completed(personal_completed_sum);

            monthTargetVO.setTarget(month_count);
            if (month_count.compareTo(zero) > 0) {
                monthTargetVO.setAmount_completed(month_amount_count);
                monthTargetVO.setCompletion_rate(month_amount_count.multiply(hundred).divide(monthTargetVO.getTarget(), 2, RoundingMode.HALF_UP));
            } else {
                monthTargetVO.setAmount_completed(zero);
                monthTargetVO.setCompletion_rate(zero);
            }
            // todo 新增月度维护目标 完成金额 完成率统计 分为个人和公司
            if (monthTargetVO.getUphold_target().compareTo(zero) > 0) {
                monthTargetVO.setUphold_rate(uphold_completed_sum.multiply(hundred).divide(monthTargetVO.getUphold_target(), 2, RoundingMode.HALF_UP));
            } else {
                monthTargetVO.setUphold_rate(zero);
            }
            if (monthTargetVO.getPersonal_target().compareTo(zero) > 0) {
                monthTargetVO.setPersonal_rate(personal_completed_sum.multiply(hundred).divide(monthTargetVO.getPersonal_target(), 2, RoundingMode.HALF_UP));
            } else {
                monthTargetVO.setPersonal_rate(zero);
            }
            amount_completed = amount_completed.add(month_amount_count);
            monthTargetVO.setWeek_completion_detail_list(tmp);
            month_target_list.add(monthTargetVO);
        }
        vo.setMonth_target_list(month_target_list);
        vo.setAmount_completed(amount_completed);
        if (vo.getSum().compareTo(zero) > 0) {
            vo.setCompletion_rate(vo.getAmount_completed().multiply(hundred).divide(vo.getSum(), 2, RoundingMode.HALF_UP));
        } else {
            vo.setCompletion_rate(zero);
        }
        vo.getMonth_target_list().forEach(month -> {
            month.getWeek_completion_detail_list().forEach(week -> {
                week.getWeekCompletionTypeVOList().forEach(typeVO -> {
                    if (vo.getNeed_fill()) {
                        typeVO.setTarget(null);
                    }
                });
            });
        });
        return vo;
    }

    @Override
    public Boolean calibration(Integer year, Integer type, Long user_id, BigDecimal complete_amount) {
        Year yearData = yearMapper.selectOne(Wrappers.<Year>lambdaQuery().eq(Year::getYear, year).eq(Year::getType, type));
        if (yearData == null) {
            throw new CommonException("年度数据不存在");
        }
        SaleYearTarget one = this.getOne(Wrappers.<SaleYearTarget>lambdaQuery().eq(SaleYearTarget::getYear_id, yearData.getId()).eq(SaleYearTarget::getUser_id, user_id));
        if (one == null) {
            throw new CommonException("用户年度目标数据不存在");
        }
        one.setTarget_quota(complete_amount);
        return this.updateById(one);
    }

    @Override
    public SaleYearTargetSummaryVO querySaleAllYearTargetSummary(Integer year, Long user_id) {
        List<Long> boss_ids = new ArrayList<>(Arrays.asList(BossUserEnum.values())).stream().map(BossUserEnum::getId).collect(Collectors.toList());
        LocalDate begin_date = LocalDate.of(year, 1, 1);
        LocalDate end_date = LocalDate.of(year, 12, 31);
        // 先查询出年度数据
        List<Year> yearData = yearMapper.selectList(Wrappers.<Year>lambdaQuery().eq(Year::getYear, year).in(Year::getType, 1, 2));
        SaleYearTargetSummaryVO vo = new SaleYearTargetSummaryVO();
        vo.setYear(year.toString());
        vo.setType(3);
        if (CollectionUtils.isEmpty(yearData)) {
            return vo;
        }
        List<Long> year_ids = yearData.stream().map(Year::getId).collect(Collectors.toList());
        List<SaleYearTarget> saleYearTarget = this.list(Wrappers.<SaleYearTarget>lambdaQuery().in(SaleYearTarget::getYear_id, year_ids).eq(SaleYearTarget::getUser_id, user_id));
        if (CollectionUtils.isEmpty(saleYearTarget)) {
            throw new CommonException("此年度主管未给您设置目标，请先设置年度目标");
        }
        BigDecimal sum = new BigDecimal(0);
        for (SaleYearTarget target : saleYearTarget) {
            sum = sum.add(target.getTarget_quota());
        }
        vo.setSum(sum);
        // 查询周数据
        List<YearWeek> weekList = yearWeekService.list(Wrappers.<YearWeek>lambdaQuery().in(YearWeek::getYear_id, year_ids));
        // 找出需要查询的周id集合
        List<Long> week_ids = weekList.stream().map(YearWeek::getId).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(week_ids)) {
            week_ids.add(-1L);
        }
        // 查询出用户每周的目标
        List<SaleWeekTarget> saleWeekTargetList = saleWeekTargetService.list(Wrappers.<SaleWeekTarget>lambdaQuery().eq(SaleWeekTarget::getUser_id, user_id).in(SaleWeekTarget::getWeek_id, week_ids));
        if (CollectionUtils.isEmpty(saleWeekTargetList)) {
            // 未填写目标 设置可填写
            vo.setNeed_fill(true);
        }
        // 查出当前人跟进的客户
        List<CustomerInfo> customer_info_list = customerInfoService.list(Wrappers.<CustomerInfo>lambdaQuery().eq(CustomerInfo::getMaintenance_staff_id, user_id).isNull(CustomerInfo::getDeleted_at));
        Map<Long, List<CustomerInfo>> customer_info_map = customer_info_list.stream().collect(Collectors.groupingBy(CustomerInfo::getId));
        List<Long> customer_ids = customer_info_list.stream().map(CustomerInfo::getId).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(customer_ids)) {
            customer_ids.add(-1L);
        }
        Map<Long, List<SaleWeekCustomerTarget>> sale_week_customer_target_map = saleWeekCustomerTargetService.list(Wrappers.<SaleWeekCustomerTarget>lambdaQuery().eq(SaleWeekCustomerTarget::getUser_id, user_id).in(SaleWeekCustomerTarget::getWeek_id, week_ids).in(SaleWeekCustomerTarget::getCustomer_id, customer_ids)).stream().collect(Collectors.groupingBy(SaleWeekCustomerTarget::getWeek_id));
        List<Long> company_customer_ids = customer_info_list.stream().filter(item -> boss_ids.contains(item.getPerson_in_charge_id())).map(CustomerInfo::getId).collect(Collectors.toList());
        List<Long> my_customer_ids = customer_info_list.stream().filter(item -> !boss_ids.contains(item.getPerson_in_charge_id())).map(CustomerInfo::getId).collect(Collectors.toList());
        // 查询出合同
        List<ContractApply> contractApplyList = contractApplyMapper.queryEffectiveContractList(begin_date, end_date, customer_ids).stream().filter(contract -> contract.getFlow_applyer_id().equals(user_id)).collect(Collectors.toList());
        // 查询出当前人的每周需要拜访的客户数据
        List<MonthTargetVO> month_target_list = new ArrayList<>();

        BigDecimal amount_completed = new BigDecimal(0);

        BigDecimal zero = new BigDecimal(0).setScale(2, RoundingMode.HALF_UP);
        List<WeekCompletionDetailVO> weekCompletionDetailVOList = new ArrayList<>();
        // 组装数据
        for (YearWeek week : weekList) {
            WeekCompletionDetailVO weekCompletionDetailVO = new WeekCompletionDetailVO();
            weekCompletionDetailVO.setId(week.getId());
            weekCompletionDetailVO.setYear_id(week.getYear_id());
            weekCompletionDetailVO.setMonth(week.getMonth());
            weekCompletionDetailVO.setBegin_date(week.getBegin_date());
            weekCompletionDetailVO.setEnd_date(week.getEnd_date());
            // 找到本周需要拜访客户
            List<CustomerInfo> collect = customer_info_list.stream().filter(customer -> customer.getNext_visit_time() != null
                    && (customer.getNext_visit_time().isAfter(week.getBegin_date()) || customer.getNext_visit_time().equals(week.getBegin_date()))
                    && (customer.getNext_visit_time().isBefore(week.getEnd_date()) || customer.getNext_visit_time().equals(week.getEnd_date()))).collect(Collectors.toList());
            // 找出本周设定目标的客户数据
            List<SaleWeekCustomerTarget> saleWeekCustomerTargetList = sale_week_customer_target_map.get(week.getId());
            if (saleWeekCustomerTargetList == null) {
                saleWeekCustomerTargetList = new ArrayList<>();
            }
            List<WeekCompletionTypeVO> weekCompletionTypeVOList = new ArrayList<>();
            BigDecimal week_target = new BigDecimal(0);
            for (int i = 1; i < 3; i++) {
                int index = i;
                List<SaleWeekTarget> saleWeekTarget = saleWeekTargetList.stream().filter(item -> item.getWeek_id().equals(week.getId()) && item.getType() == index).collect(Collectors.toList());
                List<SaleWeekCustomerTarget> list;
                List<ContractApply> contractList;
                List<CustomerInfo> customerInfoList;
                if (i == 1) {//如果是公司
                    customerInfoList = collect.stream().filter(item -> boss_ids.contains(item.getPerson_in_charge_id())).collect(Collectors.toList());
                    list = saleWeekCustomerTargetList.stream().filter(item -> company_customer_ids.contains(item.getCustomer_id())).collect(Collectors.toList());
                    // 获取出符合时间段的客户合同数据
                    contractList = contractApplyList.stream().filter(item -> company_customer_ids.contains(item.getCustomer_id()) && (item.getSign_date().isAfter(week.getBegin_date()) || item.getSign_date().equals(week.getBegin_date())) && (item.getSign_date().isBefore(week.getEnd_date()) || item.getSign_date().equals(week.getEnd_date()))).collect(Collectors.toList());
                } else {// 如果是个人
                    customerInfoList = collect.stream().filter(item -> !boss_ids.contains(item.getPerson_in_charge_id())).collect(Collectors.toList());
                    list = saleWeekCustomerTargetList.stream().filter(item -> my_customer_ids.contains(item.getCustomer_id())).collect(Collectors.toList());
                    // 获取出符合时间段的客户合同数据
                    contractList = contractApplyList.stream().filter(item -> my_customer_ids.contains(item.getCustomer_id()) && (item.getSign_date().isAfter(week.getBegin_date()) || item.getSign_date().equals(week.getBegin_date())) && (item.getSign_date().isBefore(week.getEnd_date()) || item.getSign_date().equals(week.getEnd_date()))).collect(Collectors.toList());
                }
                // 加入每周的维护和个人的成交客户数据
                List<WeekTransactedCustomerVO> weekTransactedCustomerVOList = new ArrayList<>();
                for (SaleWeekCustomerTarget target : list) {
                    WeekTransactedCustomerVO weekTransactedCustomerVO = new WeekTransactedCustomerVO();
                    weekTransactedCustomerVO.setTarget(target.getTarget_quota());
                    if (customer_info_map.containsKey(target.getCustomer_id())) {
                        weekTransactedCustomerVO.setName(customer_info_map.get(target.getCustomer_id()).get(0).getName());
                        weekTransactedCustomerVO.setId(customer_info_map.get(target.getCustomer_id()).get(0).getId());
                    } else {
                        weekTransactedCustomerVO.setName("未知");
                        weekTransactedCustomerVO.setId(-1L);
                    }
                    weekTransactedCustomerVOList.add(weekTransactedCustomerVO);
                }
                WeekCompletionTypeVO weekCompletionTypeVO = new WeekCompletionTypeVO();
                // 设置需要拜访的客户数据
                weekCompletionTypeVO.setNeed_visit_customer_list(
                        customerInfoList.stream().map(item -> {
                            BaseWeekCustomerVO customerVO = new BaseWeekCustomerVO();
                            customerVO.setId(item.getId());
                            customerVO.setName(item.getName());
                            return customerVO;
                        }).collect(Collectors.toList())
                );
                weekCompletionTypeVO.setType(i);
                if (CollectionUtils.isNotEmpty(saleWeekTarget)) {
                    weekCompletionTypeVO.setTarget(saleWeekTarget.get(0).getTarget_quota());
                } else {
                    weekCompletionTypeVO.setTarget(zero);
                }
                week_target = week_target.add(weekCompletionTypeVO.getTarget());
                BigDecimal week_type_amount_count = new BigDecimal(0);
                // 统计完成金额
                for (ContractApply contractApply : contractList) {
                    week_type_amount_count = week_type_amount_count.add(contractApply.getDiscounted_price());
                }
                if (week_type_amount_count.compareTo(zero) > 0) {
                    // 单位从元换到万元
                    week_type_amount_count = week_type_amount_count.divide(ten_thousand, 2, RoundingMode.HALF_UP);
                    weekCompletionTypeVO.setAmount_completed(week_type_amount_count);
                    if (weekCompletionTypeVO.getTarget().compareTo(zero) > 0) {
                        weekCompletionTypeVO.setCompletion_rate(week_type_amount_count.multiply(hundred).divide(weekCompletionTypeVO.getTarget(), 2, RoundingMode.HALF_UP));
                    } else {
                        weekCompletionTypeVO.setCompletion_rate(zero);
                    }
                } else {
                    weekCompletionTypeVO.setAmount_completed(zero);
                    weekCompletionTypeVO.setCompletion_rate(zero);
                }
                weekCompletionTypeVO.setWeekTransactedCustomerVOList(weekTransactedCustomerVOList);
                weekCompletionTypeVOList.add(weekCompletionTypeVO);
            }
            weekCompletionDetailVO.setWeekCompletionTypeVOList(weekCompletionTypeVOList);
            weekCompletionDetailVO.setTarget(week_target);
            weekCompletionDetailVOList.add(weekCompletionDetailVO);
        }
        // 按照月进行分组
        Map<Integer, List<WeekCompletionDetailVO>> listMap = weekCompletionDetailVOList.stream().collect(Collectors.groupingBy(WeekCompletionDetailVO::getMonth));
        Set<Integer> keys = listMap.keySet();
        for (Integer key : keys) {
            MonthTargetVO monthTargetVO = new MonthTargetVO();
            monthTargetVO.setMonth(key);
            List<WeekCompletionDetailVO> tmp = listMap.get(key);
            BigDecimal month_count = new BigDecimal(0);
            BigDecimal month_amount_count = new BigDecimal(0);
            for (WeekCompletionDetailVO weekCompletionDetailVO : tmp) {
                month_count = month_count.add(weekCompletionDetailVO.getTarget());
                for (WeekCompletionTypeVO weekCompletionTypeVO : weekCompletionDetailVO.getWeekCompletionTypeVOList()) {
                    month_amount_count = month_amount_count.add(weekCompletionTypeVO.getAmount_completed());
                }
            }
            monthTargetVO.setTarget(month_count);
            if (month_count.compareTo(zero) > 0) {
                monthTargetVO.setAmount_completed(month_amount_count);
                monthTargetVO.setCompletion_rate(month_amount_count.multiply(hundred).divide(monthTargetVO.getTarget(), 2, RoundingMode.HALF_UP));
            } else {
                monthTargetVO.setAmount_completed(zero);
                monthTargetVO.setCompletion_rate(zero);
            }
            amount_completed = amount_completed.add(month_amount_count);
            monthTargetVO.setWeek_completion_detail_list(tmp);
            month_target_list.add(monthTargetVO);
        }
        vo.setMonth_target_list(month_target_list);
        vo.setAmount_completed(amount_completed);
        if (vo.getSum().compareTo(zero) > 0) {
            vo.setCompletion_rate(vo.getAmount_completed().multiply(hundred).divide(vo.getSum(), 2, RoundingMode.HALF_UP));
        } else {
            vo.setCompletion_rate(zero);
        }
        vo.getMonth_target_list().forEach(month -> {
            month.getWeek_completion_detail_list().forEach(week -> {
                week.getWeekCompletionTypeVOList().forEach(typeVO -> {
                    if (vo.getNeed_fill()) {
                        typeVO.setTarget(null);
                    }
                });
            });
        });
        return vo;
    }
}

